package com.whcoding.multithreading.thredpool;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.junit.Test;

import java.util.concurrent.*;

/**
 * @program: spring-boot-learning
 * @description: 多线程创建：线程池
 * @author: whcoding
 * @create: 2022-06-10 14:36
 **/
public class MyThreadPoolCreate {

	public ThreadFactory namedThreadFactory =
			new ThreadFactoryBuilder().
					setNameFormat("thread-call-runner-%d").build();

	/**
	 * 1、corePoolSize线程池的核心线程数
	 * 2、maximumPoolSize能容纳的最大线程数
	 * 3、keepAliveTime空闲线程存活时间
	 * 4、unit 存活的时间单位
	 * 5、workQueue 存放提交但未执行任务的队列
	 * 6、threadFactory 创建线程的工厂类
	 * 7、handler 等待队列满后的拒绝策略
	 */
	private ExecutorService taskExe =
			new ThreadPoolExecutor(
					10,
					20,
					200L,
					TimeUnit.MILLISECONDS,
					new LinkedBlockingQueue<Runnable>(),
					namedThreadFactory);

	@Test
	public void MyThreadCreatePoolTest2(){
		for (int i = 0; i < 500; i++) {

			taskExe.execute(() -> {
				System.out.println(Thread.currentThread().getName() + "===>办理业务");
			});
		}
	}
	/**
	 * corePoolSize：线程池中所保存的核心线程数，包括空闲线程
	 * maximumPoolSize：池中允许的最大线程数。
	 * keepAliveTime：线程池中的空闲线程所能持续的最长时间，
	 * 当线程池中的线程数量小于 corePoolSize 时，
	 * 如果里面有线程的空闲时间超过了 keepAliveTime，
	 * 就将其移除线程池，这样，可以动态地调整线程池中线程的数量。
	 * unit：持续时间的单位。
	 * workQueue：任务执行前保存任务的队列，仅保存由 execute 方法提交的 Runnable 任务。
	 **/
	@Test
	public void MyThreadCreatePoolTest(){

		//方法一:不推荐
		//创建带有5个线程的线程池
		//返回的实际上是ExecutorService,而ExecutorService是Executor的子接口
		Executor threadPool = Executors.newFixedThreadPool(5);
		for(int i = 0 ;i < 10 ; i++) {
			threadPool.execute(new Runnable() {
				public void run() {
					System.out.println(Thread.currentThread().getName()+" is running");
				}
			});
		}

		//方法二:
		//创建ThreadPoolExecutor线程池对象，并初始化该对象的各种参数
		//其中线程池工厂参数用于创建线程
		ExecutorService executorService = new
				ThreadPoolExecutor(3,
				5,
				1L,
				TimeUnit.SECONDS,
				new ArrayBlockingQueue<>(3),
				Executors.defaultThreadFactory(),
				new ThreadPoolExecutor.AbortPolicy());

		for (int i = 0; i < 5; i++) {
			executorService.execute(() -> {
				System.out.println(Thread.currentThread().getName() + "===>办理业务");
			});
		}

	}
}
